/**
* 1.基本元素
*   数据，函数
*   数据：基本数据类型数据，对象，数组
*   函数：拥有入口，出口的完整代码段。
*   ××注意，本框架要求所有函数都使用纯函数。不要使用函数嵌套结构。
* 形态1：$f(json) 配置库
* 形态2：$f("")   加载一个函数
* 形态3：$f("",data...) 执行一个函数
*/
(function(window){
  var HRFrame = function(){
    var FNStore={};
    var FNStoreOrigin={};
    var STStore={};

    FNStoreOrigin["curry"]=FNStore["curry"]=function(_fnName){
      var argumentsLength=FNStoreOrigin[_fnName].length;
      var argumentsArray=[];
      var rtnFn = function(){
        var argu = Array.prototype.slice.call(arguments);
        if(argumentsArray.length+argu.length<argumentsLength){
          argumentsArray = argumentsArray.concat(argu);
          return rtnFn;
        }else{
          var param =argumentsArray.concat(argu);
          var rtn = FNStoreOrigin[_fnName].apply(STStore,param);
          return rtn;
        }
      };
      return rtnFn;
    }

    FNStoreOrigin["df"]=FNStore["df"]=function(_fnName,_fn){
      FNStoreOrigin[_fnName]=_fn;
      var rtnFn = FNStore["curry"](_fnName);
      FNStore[_fnName]=rtnFn;
      return rtnFn;
    };

    FNStoreOrigin["comp"]=FNStore["comp"]=function(){
      var argu = Array.prototype.slice.call(arguments);
      var rtnFn = function(_val){
        var tempval = argu[argu.length-1](_val);
        for(var i =argu.length-2;i>=0;i--){
          tempval=argu[i](tempval);
        }
        return tempval;
      };
      return rtnFn;
    };


    STStore.HRFrameConfig = {
      frontmode:false,
      extension:".html",
      async:true,
      splitchar:/\./g,
      path:"app"
    };


    //调用函数
    var CallFunction = function(){
      var argus=Array.prototype.slice.call(arguments);
      var _fn =FNStoreOrigin[argus[0]];
      if(typeof(_fn)=="undefined"){
        var success = $f("LoadFN",argus[0],false);
        _fn=FNStoreOrigin[argus[0]];
      }
      if(_fn==undefined){
        console.log(argus[0]+"看起来加载失败了呢。");
        return undefined;
      }else{
        var rtnFn = FNStore["curry"](argus[0]);
        var rtnVal = rtnFn.apply(STStore,argus.splice(1));
        return rtnVal||rtnFn;
      }
    };

    var HRFn = function() {
      var argus = Array.prototype.slice.call(arguments);
      if (argus.length == 0) {
        console.log("error: 你没有传参数，HR无法调用任何有用的函数。")
        return null;
      }
      if (argus.length == 1) {
        var argument = argus[0];
        if (typeof(argument) == "string") {
          var _fn = FNStore[argus[0]];
          if(_fn==undefined){
          $f("LoadFN", argument, false);
          }
          _fn = FNStore[argus[0]];
          return _fn;
        } else if (typeof(argument) == "object") {
          //配置框架
          if (argument.async != undefined && argument.async != null) {
            STStore.HRFrameConfig.async = argument.async;
          }
          if (argument.splitchar != undefined && argument.splitchar != null) {
            STStore.HRFrameConfig.splitchar = argument.splitchar;
          }
          if (argument.path != undefined && argument.path != null) {
            STStore.HRFrameConfig.path = argument.path;
          }
          if (argument.extension != undefined && argument.extension != null) {
            STStore.HRFrameConfig.extension= argument.extension;
          }
          if (argument.frontmode!= undefined && argument.frontmode!= null) {
            STStore.HRFrameConfig.frontmode= argument.frontmode;
          }
          return true;
        } else if (typeof(argument) == "function") {
          var argumentsLength=argument.length;
          var argumentsArray=[];
          var fn = argument;
          var rtnFn = function(){
            var argu = Array.prototype.slice.call(arguments);
            if(argumentsArray.length+argu.length<argumentsLength){
              argumentsArray = argumentsArray.concat(argu);
              return rtnFn;
            }else{
              var param =argumentsArray.concat(argu);
              var rtn = fn.apply(STStore,param);
              return rtn;
            }
          };
          return rtnFn;
        }
      } else {
        //执行函数
        return CallFunction.apply(STStore, argus);
      }
    };
    HRFn.data=STStore;
    HRFn.fn=FNStore;

    return HRFn;
  };

  window.$F = window.$f = window.HRFrame = HRFrame();
  //从远端读取库文件

  $f("df","LoadFN",function(_fileName,_async){
    var addAnnotation=$f(function(filename,jscode){return jscode +"\n\n //# sourceURL="+filename+".js"});
    var addAnnotation=addAnnotation(_fileName);
    var evalFile = $f(function(jscode){return eval(jscode)});
    var fileURL = $f(function(HRFrameConfig,_fileName){return HRFrameConfig.path+"/"+_fileName.replace(HRFrameConfig.splitchar,"/")+".js?time"+new Date().getMilliseconds()});
    var fileURL=fileURL(this.HRFrameConfig);
    var getRequest=$f(function(_async,url){
      var httpReq = new XMLHttpRequest();
      httpReq.open("GET",url,_async);
      return httpReq;
    });
    getRequest=getRequest(_async);
    var getFile=$f(function(httpReq,fn){
      httpReq.onreadystatechange=function(){
        if(httpReq.readyState==4&&httpReq.status==200){
          fn(httpReq.responseText);
        }
      };
      return httpReq.send();
    });
    var link1 = $f("comp",getRequest,fileURL);
    var link2 = $f("comp",evalFile,addAnnotation);
    return getFile(link1(_fileName),link2);
  });

  $f("df","GetFileHttpRequest",function(_method,_async,_url){
    var httpReq = new XMLHttpRequest();
    httpReq.open(_method,_url,_async);
    return httpReq;
  });
  $f("df","SendFileRequest",function(_httpReq,_fn){
    _httpReq.onreadystatechange=function(){
      if(_httpReq.readyState==4&&_httpReq.status==200){
        _fn(_httpReq.responseText);
      }
    };
    _httpReq.send();
  });
  $f("df","ajax",function(_url,_data,_method,_success){
    return $.ajax({
        url:_url,
        data:_data,
        type:_method,
        success:_success
      });
  });
  $f("df","Render",function(_pageName,_reqFn,_resFn){
    var fileURL = $f(function(HRFrameConfig,_fileName){return HRFrameConfig.path+"/"+_fileName.replace(HRFrameConfig.splitchar,"/")+".html?time"+new Date().getMilliseconds()});
    var url = fileURL(this.HRFrameConfig,_pageName);
    var resFn = $f(_resFn);
    //获取页面代码
    var req = $F("GetFileHttpRequest","get",true,url);
    var after = function(page){
      resFn(page);
      var requestData = $f(_reqFn)();
      var request = $f("ajax");
      request(requestData.url,requestData.data,requestData.method,resFn);
    };
    $f("SendFileRequest",req,after);
  });

  $f("df","tppl",function(tpl,data){
    /**
    * tppl.js 极致性能的 JS 模板引擎
    * Github：https://github.com/jojoin/tppl
    * 作者：杨捷
    * 邮箱：yangjie@jojoin.com
    *
    * @param tpl {String}    模板字符串
    * @param data {Object}   模板数据（不传或为null时返回渲染方法）
    *
    * @return  {String}    渲染结果
    * @return  {Function}  渲染方法
    *
    * 增加undefined判断
    *
    */
    var fn =  function(d) {
      var i, k = [], v = [];
      for (i in d) {
        k.push(i);
        v.push(d[i]);
      };
      return (new Function(k, fn.$)).apply(d, v);
    };
    if(!fn.$){
      var tpls = tpl.split('[:');
      fn.$ = "var $empty=''; var $reg = RegExp(/object|undefined|function/i); console.log($reg.test(typeof(type))?'111':type); var $=''";
      for(var t in tpls){
        var p = tpls[t].split(':]');
        if(t!=0){
          fn.$ += '='==p[0].charAt(0)
          ? "+($reg.test(typeof("+p[0].substr(1)+"))?$empty:"+p[0].substr(1)+")"
          : ";"+p[0].replace(/\r\n/g, '')+"$=$"
        }
        // 支持 <pre> 和 [::] 包裹的 js 代码
        fn.$ += "+'"+p[p.length-1].replace(/\'/g,"\\'").replace(/\r\n/g, '\\n').replace(/\n/g, '\\n').replace(/\r/g, '\\n')+"'";
      }
      fn.$ += ";return $;";
      // log(fn.$);
    }

    return data ? fn(data) : fn;

  });

  $f("df","set",function(_key,_data){
    this[_key]=_data;
  });

  $f("df","get",function(_key){
    return this[_key];
  });

})(window);
